﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace ManPowerEngine
{
	/// <summary>
	/// Text Renderer component of a game object.
	/// </summary>
	public class TextRenderer : RendererBase
	{
		private TextBlock mTextBlock;
		private SolidColorBrush mColorBrush;
		private LinearGradientBrush mGradientBrush;
		private bool mGradientMode = false;

		/// <summary>
		/// initialize a text renderer
		/// </summary>
		/// <param name="text">The text to be shown in this renderer</param>
		/// <param name="width">Width in pixel</param>
		/// <param name="height">Height in pixel</param>
		/// <param name="zindex">Z-Index. The bigger the higher.</param>
		public TextRenderer(string text, int width, int height, int zindex)
			: base(width, height, zindex)
		{
			mTextBlock = new TextBlock();
			{
				mTextBlock.Height = Height;
				mTextBlock.Width = Width;
				mTextBlock.Text = text;
				mTextBlock.TextWrapping = TextWrapping.Wrap;
			}

			mColorBrush = new SolidColorBrush(Colors.Black);
			mGradientBrush = new LinearGradientBrush(new GradientStopCollection(), 90);
			mGradientBrush.GradientStops.Add(new GradientStop { Color = Colors.Black, Offset = 0 });
			mGradientBrush.GradientStops.Add(new GradientStop { Color = Colors.White, Offset = 1 });
			mTextBlock.Foreground = mColorBrush;
			mElement = mTextBlock;
		}

		/// <summary>
		/// Turn on or off the gradient mode.
		/// </summary>
		public bool GradientMode
		{
			get
			{
				return mGradientMode;
			}
			set
			{
				if (mGradientMode != value)
				{
					mGradientMode = value;
					if (mGradientMode) {
						mTextBlock.Foreground = mGradientBrush;
					} else {
						mTextBlock.Foreground = mColorBrush;
					}
				}
			}
		}

		/// <summary>
		/// A helper function for setting up font.
		/// </summary>
		/// <param name="font">The font-family string</param>
		/// <param name="size">Font size in points</param>
		/// <param name="bold">Is this bold?</param>
		/// <param name="italic">Is this italic?</param>
		public void SetFont(string font, double size, bool bold, bool italic)
		{
			FontFamily = font;
			FontSize = size;
			Bold = bold;
			Italic = italic;
		}

		/// <summary>
		/// set the font-family of this text block.
		/// </summary>
		public string FontFamily
		{
			set
			{
				mTextBlock.FontFamily = new FontFamily(value);
			}
		}

		/// <summary>
		/// The color of this text for the solid color brush or the first color in the gradient brush
		/// </summary>
		public Color Color
		{
			get
			{
				return mColorBrush.Color;
			}
			set
			{
				mColorBrush.Color = value;
				mGradientBrush.GradientStops[0].Color = value;
			}
		}

		/// <summary>
		/// The second color for the gradient brush
		/// </summary>
		public Color SecondColor
		{
			get
			{
				return mGradientBrush.GradientStops[1].Color;
			}
			set
			{
				mGradientBrush.GradientStops[1].Color = value;
			}
		}

		/// <summary>
		/// Gets or sets the font size
		/// </summary>
		public double FontSize
		{
			get
			{
				return mTextBlock.FontSize;
			}
			set
			{
				mTextBlock.FontSize = value;
			}
		}

		/// <summary>
		/// Gets or sets whether the font is in italic style
		/// </summary>
		public bool Italic
		{
			get
			{
				return (mTextBlock.FontStyle == FontStyles.Italic);
			}
			set
			{
				if (value)
					mTextBlock.FontStyle = FontStyles.Italic;
				else
					mTextBlock.FontStyle = FontStyles.Normal;
			}
		}

		/// <summary>
		/// Gets or sets whether the font is bold
		/// </summary>
		public bool Bold
		{
			get
			{
				return (mTextBlock.FontWeight == FontWeights.Bold);
			}
			set
			{
				if (value)
					mTextBlock.FontWeight = FontWeights.Bold;
				else
					mTextBlock.FontWeight = FontWeights.Normal;
			}
		}

		/// <summary>
		/// how the text is aligned to this text block
		/// </summary>
		public TextAlignment TextAlignment
		{
			get
			{
				return mTextBlock.TextAlignment;
			}
			set
			{
				mTextBlock.TextAlignment = value;
			}
		}

		/// <summary>
		/// Gets or sets the text content of this renderer.
		/// </summary>
		public string Text
		{
			get
			{
				return mTextBlock.Text;
			}
			set
			{
				mTextBlock.Text = value;
			}
		}
	}
}
